package user;

import image.Image;

import java.io.File;
import java.util.ArrayList;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;


import servers.DrawProxy;
import user.User;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "users"
})
@XmlRootElement
public class UserDataBase {

	private static final UserDataBase instance = new UserDataBase();
	
	@XmlElementRef
	private ArrayList<User> users;
	
	private UserDataBase() {
		this.users = new ArrayList<User>();
	}

	public final static UserDataBase getInstance() {
        return instance;
    }
	
	public void loadDB() {
		File f = new File("userdatabase.db");
		if(f.exists()) {
			try {
				/* UNMARSHALLER XML TO JAVA */
				JAXBContext context = JAXBContext.newInstance(UserDataBase.class,
																User.class);
				Unmarshaller u = context.createUnmarshaller();
				for(User usr : ((UserDataBase) u.unmarshal(f)).getUsers()) {
					UserDataBase.getInstance().addUser(usr);
				}
			} catch(Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	public void addUser(User u) {
		UserDataBase.getInstance().users.add(u);
		System.out.println("user '"+u.getId()+"' added to the database");
	}
	
	public void saveDB() {
		try {
			/* MARSHALLER JAVA TO XML */
			JAXBContext context = JAXBContext.newInstance(UserDataBase.class,
															User.class);
			Marshaller m = context.createMarshaller();
			m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
			m.marshal(this, new File("userdatabase.db"));
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public Boolean isAccessGranted(String user) {
		for(User u : this.users) {
			if(u.getId().equalsIgnoreCase(user)) {
				System.out.println("\n--info : User '"+user+"' has logged in");
				System.out.println("root@server:");
				DrawProxy.nbUsers++;
				return true;
			}
		}
		System.out.println("ACCESS DENIED !");
		return false;
	}
	
	public Boolean isAccessGranted(String user, String action, Image image, Image image2) {
		for(User u : this.users) {
			if(u.getId().equalsIgnoreCase(user)) {
				if(u.getStatus() == AuthLevel.ADMIN) {
					if(action.equalsIgnoreCase("getXML")) return true;
					if(action.equalsIgnoreCase("getImagePng")) return true;
					if(action.equalsIgnoreCase("deleteItem")) return true;
					if(action.equalsIgnoreCase("getAllImagesName")) return true;
				}
				else if(u.getStatus() == AuthLevel.SIMPLE_USER) {
					if((action.equalsIgnoreCase("addArc")) && (image.getOwner().equalsIgnoreCase(user))) return true;
					if((action.equalsIgnoreCase("addEllipse")) && (image.getOwner().equalsIgnoreCase(user))) return true;
					if((action.equalsIgnoreCase("addLine")) && (image.getOwner().equalsIgnoreCase(user))) return true;
					if((action.equalsIgnoreCase("addPolygon")) && (image.getOwner().equalsIgnoreCase(user))) return true;
					if((action.equalsIgnoreCase("addRectangle")) && (image.getOwner().equalsIgnoreCase(user))) return true;
					if((action.equalsIgnoreCase("addImage")) && (image.getOwner().equalsIgnoreCase(user)) && (image2.getOwner().equalsIgnoreCase(user))) return true;
					if((action.equalsIgnoreCase("getXML")) && (image.getOwner().equalsIgnoreCase(user))) return true;
					if(action.equalsIgnoreCase("getImagePng") && (image.getOwner().equalsIgnoreCase(user))) return true;
					if((action.equalsIgnoreCase("removeItem")) && (image.getOwner().equalsIgnoreCase(user))) return true;
					if((action.equalsIgnoreCase("deleteItem")) && (image.getOwner().equalsIgnoreCase(user))) return true;
					if((action.equalsIgnoreCase("getImageShapes")) && (image.getOwner().equalsIgnoreCase(user))) return true;
					if((action.equalsIgnoreCase("getMyImagesName")) && (image.getOwner().equalsIgnoreCase(user))) return true;
				}
			}
		}
		return false;
	}
	
	public ArrayList<User> getUsers() {
		return users;
	}
}
